#include "led.h"
#include <stdbool.h>

/**
 * @brief
 *
 * @param n
 * @param m
 * @return int32_t
 */
int32_t led_setmode(ledctrl_t*p, ledctrlmode_t m)
{
    p->cmd.byte = m;
    return 0;
}
/**
 * @brief 
 * @note default execute cycle 1ms
 *
 * @param
 */
void led_control(ledctrl_t*p)
{
    p->ms++;
    if (p->ms == 50 || p->ms == 100 || p->ms == 150 || p->ms == 200) // set flickering LED if required
    {
        /*Calculate current Run LED state*/
        if (p->cmd.bit.fast_toggle || p->ms == 200) // if fast flag or slow cycle event
        {
            uint8_t NumFlashes = 0;
            if (p->cmd.bit.num_of_flash > 0)
            {
                NumFlashes = p->cmd.bit.num_of_flash * 2 - 1; // total number
            }

            /*generate LED code*/
            if (p->cmd.byte != p->cmd_prev.byte) // state changed start with active LED
            {
                if (p->cmd.bit.invert) // invert flag enable?
                {
                    p->state = false;
                }
                else
                {
                    p->state = true;
                }

                p->cnt = 1;
            }
            else // second and following LED cycle
            {
                if (p->cmd.bit.toggle) // toggle LED bit on
                {
                    p->state = !p->state;

                    if (NumFlashes) // NumFlashes defined => limited LED toggle
                    {
                        p->cnt++;

                        if (p->cnt > NumFlashes) // toggle led finished
                        {
                            if (p->cmd.bit.invert) // invert flag enable?
                            {
                                p->state = true;
                            }
                            else
                            {
                                p->state = false;
                            }

                            if (p->cnt >= (NumFlashes + 5)) // toggle time + 5 cycles low
                            {
                                p->cnt = 0;
                            }
                        }
                    }
                }
                else
                {
                    p->state = (p->cmd.byte & 0x01);
                }
            }
            p->cmd_prev.byte = p->cmd.byte;            
            if (p->state != p->state_last)
            {
                if (p->wrgpio)
                    p->wrgpio(p->state);
            }
            p->state_last = p->state;
        }
        if (p->ms == 200)
        {
            p->ms = 0;
        }
    }
}
